#include "pathological.h"

void triangle_intersect(object_t *o, ray_t *r, point_t *p)
{
	p->t = DBL_MAX;

	triangle_t *t = (triangle_t *)o;
	double mr1[4] = {-r->d.x,t->s1.x,t->s2.x,r->o.x - t->v.x},
	       mr2[4] = {-r->d.y,t->s1.y,t->s2.y,r->o.y - t->v.y},
	       mr3[4] = {-r->d.z,t->s1.z,t->s2.z,r->o.z - t->v.z};
	double *m[3] = {mr1,mr2,mr3};

	rref_3x4(m);
	if(fabs(m[0][2]) > EPSILON || fabs(m[1][2]) > EPSILON || m[0][3] < -EPSILON
		|| m[1][3] < -EPSILON || m[2][3] < -EPSILON
		|| m[1][3] + m[2][3] > 1 + EPSILON)
		return;
	p->t = m[0][3], p->x = r->o.x + p->t*r->d.x, p->y = r->o.y + p->t*r->d.y,
	p->z = r->o.z + p->t*r->d.z;
	p->n = t->n;
}

void triangle_surface_point(point_t *p, object_t *o)
{
	float r1 = ran(), r2 = ran();
	triangle_t *t = (triangle_t *)o;
	if(r1 + r2 > 1) r1 = 1 - r1, r2 = 1 - r2;
	p->x = t->v.x + r1*t->s1.x + r2*t->s2.x,
	p->y = t->v.y + r1*t->s1.y + r2*t->s2.y,
	p->z = t->v.z + r1*t->s1.z + r2*t->s2.z;
	p->n = t->n;
}

void triangle_aabb(aabb_t *aabb, object_t *o)
{
	triangle_t *t = (triangle_t *)o;
	aabb->min[0] = MIN(t->v.x,MIN(t->v.x + t->s1.x,t->v.x + t->s2.x));
	aabb->min[1] = MIN(t->v.y,MIN(t->v.y + t->s1.y,t->v.y + t->s2.y));
	aabb->min[2] = MIN(t->v.z,MIN(t->v.z + t->s1.z,t->v.z + t->s2.z));
	aabb->max[0] = MAX(t->v.x,MAX(t->v.x + t->s1.x,t->v.x + t->s2.x));
	aabb->max[1] = MAX(t->v.y,MAX(t->v.y + t->s1.y,t->v.y + t->s2.y));
	aabb->max[2] = MAX(t->v.z,MAX(t->v.z + t->s1.z,t->v.z + t->s2.z));
}

